﻿using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using SS2TC.Speech;
using SS2TC.Lexicon;

namespace SS2TC.Main
{
    // Garage entrance
    class Program
    {
        static void Main(string[] args)
        {
            CsvWriter writer = new CsvWriter(@"D:\Personal\Projects\acsr\Data\CSV\");
            writer.WriteFrequencyDataFromDatabase();
        }

        private static IEnumerable<char> ConvertToBinary(byte eachByte)
        {
            StringBuilder builder = new StringBuilder();
            byte result = (byte) (eachByte / 2);
            byte remainder;

            while (result >= 2)
            {
                remainder = (byte) (eachByte - (result * 2));
                builder.Append(remainder);
                eachByte = result;
                result = (byte)(eachByte / 2);
            }

            remainder = (byte)(eachByte - (result * 2));
            builder.Append(remainder);
            builder.Append(result);

            return builder.ToString().Reverse();
        }

        private static void Train(bool replace)
        {
            WaveFormat waveFormat = new WaveFormat();
            AudioStreamReader audioStreamReader = new AudioStreamReader(waveFormat);

            Console.WriteLine("input 1");
            Console.ReadLine();

            byte[] data1 = audioStreamReader.Read(2);
            audioStreamReader.Close();

            Noise noise = new Noise();
            byte[] filtered = noise.Filter(data1);

            Index sinhalaIndex = new Index("sinhala");

            if (replace)
            { 
                sinhalaIndex.Replace("ඈ", filtered);
            }
            else
            {
                sinhalaIndex.Add("ඈ", filtered);
            }

            AudioStreamWriter audioStreamWriter = new AudioStreamWriter(waveFormat);
            audioStreamWriter.Write(filtered);

            audioStreamWriter.Close();
        }

        private static void Play()
        {
            WaveFormat waveFormat = new WaveFormat();
            AudioStreamWriter audioStreamWriter = new AudioStreamWriter(waveFormat);

            Index sinhalaIndex = new Index("sinhala");

            foreach (byte[] sound in sinhalaIndex.Values)
            {
                audioStreamWriter.Write(sound);
            }

            audioStreamWriter.Close();
        }

        private static void Pronounce()
        {
            Index sinhalaIndex = new Index("sinhala");
            Pronouncer pronouncer = new Pronouncer(sinhalaIndex);
            pronouncer.Pronounce("ඈ");
        }

        private static void Recognize()
        {
            WaveFormat waveFormat = new WaveFormat();
            AudioStreamReader reader = new AudioStreamReader(waveFormat);

            Console.WriteLine("input 1");
            Console.ReadLine();

            byte[] data1 = reader.Read(2);
            reader.Close();

            Noise noise = new Noise();
            byte[] filtered = noise.Filter(data1);

            Index sinhalaIndex = new Index("sinhala");
            Recognizer recognizer = new Recognizer(sinhalaIndex);
            bool result = recognizer.Match(filtered);
        }

        private static void Match()
        {
            WaveFormat waveFormat = new WaveFormat();
            AudioStreamReader reader = new AudioStreamReader(waveFormat);

            Console.WriteLine("input 1");
            Console.ReadLine();

            byte[] data1 = reader.Read(1);
            reader.Close();

            Console.WriteLine("input 2");
            Console.ReadLine();

            byte[] data2 = reader.Read(1);
            reader.Close();

            Noise noise = new Noise();
            byte[] filtered1 = noise.Filter(data1);
            byte[] filtered2 = noise.Filter(data2);

            Index sinhalaIndex = new Index("sinhala");
            Recognizer recognizer = new Recognizer(sinhalaIndex);

            bool match = recognizer.Match(filtered1, filtered2);
        }

        private static void WriteGradients()
        {
            WaveFormat waveFormat = new WaveFormat();
            AudioStreamReader reader = new AudioStreamReader(waveFormat);

            Console.WriteLine("input 1");
            Console.ReadLine();

            byte[] data1 = reader.Read(2);
            reader.Close();

            Noise noise = new Noise();

            double[] slidingGradient = noise.SlidingGradient(noise.Filter(data1));

            StreamWriter writer = new StreamWriter(@"D:\Personal\Projects\acsr\Files\Support\a\5gradient.csv");

            writer.WriteLine("Sample, SlidingGradient");

            for (int i = 0; i < slidingGradient.Length; i++)
            {
                writer.WriteLine((i + 1) + ", " + (slidingGradient[i]));
            }

            writer.Close();

            AudioStreamWriter audioStreamWriter = new AudioStreamWriter(waveFormat);

            audioStreamWriter.Write(data1);

            audioStreamWriter.Close();
        }

        private static void WriteToDatabase()
        {
            WaveFormat waveFormat = new WaveFormat();
            AudioStreamReader reader = new AudioStreamReader(waveFormat);

            Console.WriteLine("input 1");
            Console.ReadLine();

            byte[] data1 = reader.Read(3);
            reader.Close();

            using (SqlConnection dbConnection = new SqlConnection(DatabaseStrings.SpeechDatabaseConnection))
            {
                dbConnection.Open();

                SqlCommand command = new SqlCommand(DatabaseStrings.InsertToVowel, dbConnection);
                command.Parameters.Add("@Letter", "æ");
                command.Parameters.Add("@SampleData", data1);
                command.ExecuteNonQuery();

                dbConnection.Close();
            }
        }

        public static void UpdateDatabase()
        {
            using (SqlConnection dbConnection = new SqlConnection(DatabaseStrings.SpeechDatabaseConnection))
            {
                dbConnection.Open();

                SqlCommand command = new SqlCommand(DatabaseStrings.UpdateLetterInVowel, dbConnection);
                command.Parameters.Add("@Letter", "ʌ");
                command.ExecuteNonQuery();

                dbConnection.Close();
            }
        }

        public static void ReadFromDatabase()
        {
            List<byte[]> all = new List<byte[]>();

            using (SqlConnection dbConnection = new SqlConnection(DatabaseStrings.SpeechDatabaseConnection))
            {
                dbConnection.Open();

                using (SqlCommand command = new SqlCommand(DatabaseStrings.SelectAllFromVowel, dbConnection))
                {
                    var reader = command.ExecuteReader();

                    while (reader.Read())
                    {
                        byte[] data = reader["SampleData"] as byte[];
                        string letter = reader["Letter"] as string;
                        all.Add(data);
                    }
                }

                dbConnection.Close();
            }

            WaveFormat waveFormat = new WaveFormat();

            foreach (var data in all)
            {
                AudioStreamWriter audioStreamWriter = new AudioStreamWriter(waveFormat);
                audioStreamWriter.Write(data);
                audioStreamWriter.Close();
                Thread.Sleep(500);
            }
        }

        private static void WriteToFile()
        {
            WaveFormat waveFormat = new WaveFormat();
            AudioStreamReader reader = new AudioStreamReader(waveFormat);

            Console.WriteLine("input 1");
            Console.ReadLine();

            byte[] data1 = reader.Read(2);
            reader.Close();

            byte[] filtered1 = new Noise().FilterDifferent(data1);

            Console.WriteLine("input 2");
            Console.ReadLine();

            byte[] data2 = reader.Read(2);
            reader.Close();

            byte[] filtered2 = new Noise().FilterDifferent(data2);

            StreamWriter writer = new StreamWriter(@"D:\Personal\Projects\acsr\Files\Support\a\2diff.csv");

            int lenght;

            lenght = filtered1.Length;

            if (filtered2.Length < filtered1.Length)
            {
                lenght = filtered2.Length;
            }

            writer.WriteLine("Sample, Byte");

            for (int i = 0; i < lenght; i++)
            {
                writer.WriteLine((i + 1) + ", " + (filtered1[i] - filtered2[i]));
            }

            writer.Close();

            //AudioStreamWriter audioStreamWriter = new AudioStreamWriter(waveFormat);

            //audioStreamWriter.Write(filtered);

            //audioStreamWriter.Close();

        //    Console.WriteLine("input 2");
        //    Console.ReadLine();

        //    byte[] data2 = reader.Read(2);
        //    reader.Close();

        //    Noise noise = new Noise();
        //    byte[] filtered1 = noise.Filter(data1);
        //    byte[] filtered2 = noise.Filter(data2);

        //    List<byte> refined1 = new List<byte>();
        //    List<byte> refined2 = new List<byte>();

        //    for (int repeatedIndex = 0; repeatedIndex < filtered1.Length; repeatedIndex++)
        //    {
        //        if (repeatedIndex != 0)
        //        {
        //            if (filtered1[repeatedIndex] != filtered1[repeatedIndex - 1])
        //            {
        //                refined1.Add(filtered1[repeatedIndex]);
        //            }
        //        }
        //        else
        //        {
        //            refined1.Add(filtered1[0]);
        //        }
        //    }

        //    for (int repeatedIndex = 0; repeatedIndex < filtered2.Length; repeatedIndex++)
        //    {
        //        if (repeatedIndex != 0)
        //        {
        //            if (filtered2[repeatedIndex] != filtered2[repeatedIndex - 1])
        //            {
        //                refined2.Add(filtered2[repeatedIndex]);
        //            }
        //        }
        //        else
        //        {
        //            refined2.Add(filtered2[0]);
        //        }
        //    }

        //    byte[] diff;

        //    if (refined1.Count < refined2.Count)
        //    {
        //        diff = new byte[refined1.Count];
        //    }
        //    else
        //    {
        //        diff = new byte[refined2.Count];
        //    }

        //    for (int repeatedIndex = 0; repeatedIndex < diff.Length; repeatedIndex++)
        //    {
        //        if (refined1[repeatedIndex] > refined2[repeatedIndex])
        //        {
        //            diff[repeatedIndex] = (byte)(refined1[repeatedIndex] - refined2[repeatedIndex]);
        //        }
        //        else
        //        {
        //            diff[repeatedIndex] = (byte)(refined2[repeatedIndex] - refined1[repeatedIndex]);
        //        }
        //    }
        }
    }
}
